package com.pisolution.actuator.client.registration;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 客户端注册监听器 负责处理客户端应用生命周期内的注册相关功能.
 *
 * @author sora
 * @version 0.1.0
 */
public class RegistrationListener implements DisposableBean {
    /** 用于以固定频率尝试注册客户端. */
    private final ScheduledExecutorService scheduler;

    /** 用于处理注册过程. */
    private final ApplicationRegister register;

    // -------------------------------------------------------------------------------------------------
    //  初始化
    // -------------------------------------------------------------------------------------------------

    public RegistrationListener(final ApplicationRegister register) {
        this.scheduler = Executors.newSingleThreadScheduledExecutor();
        this.register = register;
    }

    // -------------------------------------------------------------------------------------------------
    //  生命周期
    // -------------------------------------------------------------------------------------------------

    @Override
    public void destroy() {
        if (!this.scheduler.isShutdown()) {
            this.scheduler.shutdown();
        }
    }

    // -------------------------------------------------------------------------------------------------
    //  注册
    // -------------------------------------------------------------------------------------------------

    /**
     * 客户端应用启动后以固定频率尝试注册客户端应用.
     *
     * @param event 客户端启动就绪事件.
     */
    @SuppressWarnings("unused")
    @EventListener
    @Order
    public void onApplicationReady(ApplicationReadyEvent event) {
        this.scheduler.schedule(this.register::register, 5L, TimeUnit.SECONDS);
    }

    /**
     * 客户端关闭时尝试取消注册客户端.
     *
     * @param event 客户端关闭事件.
     */
    @EventListener
    @Order
    public void onApplicationClosed(ContextClosedEvent event) {
        final ApplicationContext context = event.getApplicationContext().getParent();
        if (context == null || "bootstrap".equals(context.getId())) {
            this.register.deregister();
        }
    }
}
